﻿namespace LaoLuo
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    /// <summary>
    /// A container whose content should be treated as a work, which has a time limit
    /// </summary>
    /// <typeparam name="T">type of work object</typeparam>
    public class Work<T>
    {
        /// <summary>
        /// init a <see cref="Work&lt;T>"/>
        /// </summary>
        /// <param name="workObject">work object</param>
        /// <param name="immediate">work should be done immediately or not</param>
        /// <param name="workTime">if <paramref name="work"/> is not immediate, time should be specified</param>
        private Work(T workObject, bool immediate, DateTime? workTime = null)
        {
            this.WorkObject = workObject;
            this.Immediate = immediate;
            this.WorkTime = workTime;
        }

        /// <summary>
        /// Gets or sets whether work should be done immediately or not
        /// </summary>
        public bool Immediate { get; set; }

        /// <summary>
        /// Time limit of work. if immediate, this can be null
        /// </summary>
        public DateTime? WorkTime { get; set; }

        /// <summary>
        /// work object
        /// </summary>
        public T WorkObject { get; set; }

        /// <summary>
        /// Gets a new immediate work
        /// </summary>
        /// <param name="workObject">work object</param>
        /// <returns>instance of <see cref="Work&lt;T>"/></returns>
        public static Work<T> NewImmediateWork(T workObject)
        {
            return new Work<T>(workObject, true);
        }

        /// <summary>
        /// Gets a new delayed work
        /// </summary>
        /// <param name="workObject">work object</param>
        /// <param name="workTime">time to do the work</param>
        /// <returns>instance of <see cref="Work&lt;T>"/></returns>
        public static Work<T> NewDelayedWork(T workObject, DateTime workTime)
        {
            return new Work<T>(workObject, false, workTime);
        }
    }
}
